from flask.views import MethodView
from flask import Flask, request, jsonify
from flask_cors import *
from werkzeug.datastructures import ImmutableMultiDict
import ast
import json
import random

import db
from template import Engine, Step
import subprocess
import os

import datetime


app = Flask(__name__)
CORS(app)



data = [
    {"name" : "安装", "steps": [
        {"name": "环境检查",
         "playbook": "http://172.16.50.89/playbooks/tale/precheck.yaml",
         "right": "tale_pre_check"},
        {"name": "依赖安装",
         "playbook": "http://172.16.50.89/playbooks/tale/install_dependence.yaml",
         "right": "tale_dep_install"},
        {"name": "Tale安装",
         "playbook": "http://172.16.50.89/playbooks/tale/install_tale.yaml",
         "right": "tale_tale_install"},
        {"name": "导入数据集",
         "playbook": "http://172.16.50.89/playbooks/tale/import_db.yaml",
         "right": "tale_db_import"},
        {"name": "启动服务",
         "playbook": "http://172.16.50.89/playbooks/tale/start_tale.yaml",
         "right": "tale_start"},
        {"name": "健康检查",
         "playbook": "http://172.16.50.89/playbooks/tale/health_check.yaml",
         "right": "tale_health_check"}
    ]},
    {"name" : "健康检查", "steps": [
        {"name" : "环境检查",
         "playbook": "http://172.16.50.89/playbooks/tale/precheck.yaml",
         "right": "tale_pre_check"},
        {"name" : "健康检查",
         "playbook": "http://172.16.50.89/playbooks/tale/health_check.yaml",
         "right": "tale_health_check"}
    ]},
    {"name" : "备份", "steps": [
        {"name" : "环境检查",
         "playbook": "http://172.16.50.89/playbooks/tale/precheck.yaml",
         "right": "tale_pre_check"},
        {"name" : "数据备份",
         "playbook": "http://172.16.50.89/playbooks/tale/backup.yaml",
         "right": "tale_db_backup"}
    ]}
]


def generate():
    client = db.DBClient()
    
    result = client.find_config_record('tale.database')
    import subprocess
    s = subprocess.Popen(["ls", "/usr/share/nginx/html/database/backup"], stdout=subprocess.PIPE)
    m = map(lambda x: x.strip().decode("utf8"), s.stdout.read().split())
    for i in m:
        _r = "backup/{0}".format(i)
        if _r not in result:
            result.append(_r)

    client.update_config_record('tale.database', result)


class ConfigView(MethodView):

    def get(self):
        generate()
        leaf = False
        client = db.DBClient()
        names = []
        if request:
            name = request.args.get('name')
            if name is not None:
                result = client.find_config_record(name)
                if isinstance(result, list) or isinstance(result, str):
                    leaf = True
                else:
                    names = list(result.keys())
            else:
                result = client.find_config_record()
        return jsonify({"code": 20000, "result": result, "leaf": leaf, "names": names})

    def post(self):
        client = db.DBClient()
        if request:
            data = json.loads(request.data.decode("utf-8").replace("'",'"'))
            results = client.update_config_record(data["name"], data["value"])
        return jsonify({"code": 20000, "result": results})


class TaleView(MethodView):
    def get(self):
        return jsonify({"code": 20000, "templates": data})



class TaskView(MethodView):

    def get(self):
        client = db.DBClient()
        id = request.args.get("id", None)
        tasks = client.get_task(id)
        return jsonify({"code": 20000, "result": tasks})

    def post(self):
        client = db.DBClient()
        task_name = json.loads(request.data.decode("utf8")).get("name")
        form = json.loads(request.data.decode("utf8")).get("form")


        for i in data:
            if i['name'] == task_name:
                task = i
        _now = datetime.datetime.now()
        host = client.find_config_record('tale.scheduler.{0}'.format(form['scheduler']))
        if type(host) == type([]):
            host = host[random.randint(0, len(host)-1)]
        if task_name == "健康检查":
            arguments = {'scheduler': form['scheduler'],
                         'host': host,
                         'now': _now}
        elif task_name == "安装":
            arguments = {'scheduler': form['scheduler'],
                         'host': host,
                         'now': _now,
                         'database':  form['database'],
                         'version': form['version']}
        elif task_name == "备份":
            arguments = {'scheduler': form['scheduler'],
                         'host': host,
                         'now': _now,
                         'backupdelta': form['backupdelta']}
        _data = {"name": task["name"], "status": "prepared", "steps": task['steps'], "now": _now,
                 "form": form, "arguments": arguments}
        
        client.insert_task(_data)
        s = subprocess.Popen(['python3.4', 'engine.py', str(_data["_id"])])
        print(_data["_id"])
        return jsonify({"code": 20000})


class RightView(MethodView):
    def get(self):
        client = db.DBClient()
        data = []
        right_col = client.get_db()[client.right_col_name]
        t = request.args.get("time")
        for i in right_col.find({}):
            print(i.get("time"))
            data.append({"_id": str(i['_id']), "name": i['name'], "right": i['ret'], "time": i.get('time', [])})
        return jsonify({"code": 20000, "rights": data})


    def post(self):
        client = db.DBClient()
        _id = json.loads(request.data.decode("utf8")).get("_id")
        ret = json.loads(request.data.decode("utf8")).get("right")
        t = json.loads(request.data.decode("utf8")).get("time")
        if "time" in json.loads(request.data.decode("utf8")):
            client.update_right({"_id": _id, "time": t})    
        else:
            client.update_right({"_id": _id, "ret": ret})    
        return jsonify({"code": 20000})


app.add_url_rule("/config/", view_func=ConfigView.as_view("config"))
app.add_url_rule("/template/", view_func=TaleView.as_view("template"))
app.add_url_rule("/task/", view_func=TaskView.as_view("task"))
app.add_url_rule("/right/", view_func=RightView.as_view("right"))



if __name__ == "__main__":
    app.run(host='0.0.0.0', debug=True)
